package com.mzm.util.persistency;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import dnl.toolbox.api.PaginationInfo;


/**
 * 
 * @author Daniel Orr
 *
 * @param <T>
 * @param <ID>
 */
public interface GenericDao<T, ID extends Serializable> {

	/**
	 * Store a new object
	 * @param entity The object to store
	 * @return ID the identifier of the newly created instance
	 */
    ID create(T entity);

	/**
	 * Update an existing object
	 * @param entity The object to persist. The object version will
	 * change after a successful update.
	 */
    void update(T entity);
    
    /**
     * Delete an existing object from persistent storage
     * @param entity The object to delete.
     */
    void delete(T entity);
    
    /**
     * Deletes by Id.
     * @param id
     */
    void delete(ID id);

    /**
     * 
     * @param entity
     */
    void merge(T entity);
    
    /**
     * Refresh an existing object with any changes which took place at the data store.
     * @param entity The object to refresh.
     */
    void refresh(T entity);

    /**
     * Creates or updates existing object
     * @param entity parameter to save or update
     */
    void createOrUpdate(T entity);
    
    /**
     * Delete all objects of type <code>T</code>
     *
     */
    void deleteAll();
    
    //finders   
    /**
     * Find all objects of type <code>T</code>
     */
    Collection<T> findAll() ;

    /**
     * Find an object by its identifier
     * @param id The object ID to look for
     * @param lock Hibernate lock mode (TODO: remove?)
     * @return The object, or null if could not find it.
     */
    T findById(ID id, boolean lock);
    
    /**
     * Find all objects matching the fields of an example object
     * @param example The example object
     * @return The objects found.
     */
	Collection<T> findByExample(T example);
	
	/**
	 * 
	 * @param startIndex
	 * @param pageSize
	 * @param orderBy
	 * @param asc TODO
	 * @return
	 */
	Collection<T> getPage(PaginationInfo paginationInfo);
	
	/**
	 * Find a single object by example
	 * @param example An example object - all non-null fields must match.
	 * @return The object found
	 * @throws org.hibernate.NonUniqueResultException More than one match
	 *         was found. (TODO: replace with non-Hibernate exception)
	 */
	T findUniqueResultByExample(final T example);
	
	int getTotalNumberOfEntities();

	long count();

	List<T> find(String queryString, Object... values);
	
}
